package com.example.util;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.TreeMap;

/**
 * 哈希工具类
 */
public class HashUtil {

    /**
     * 生成字符串的MD5哈希
     * 
     * @param text 需要哈希的文本
     * @return MD5哈希值
     */
    public static String md5(String text) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hashBytes = md.digest(text.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hashBytes);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5哈希计算失败", e);
        }
    }

    /**
     * 生成SQL的哈希值
     * 
     * @param sql SQL语句
     * @return 哈希值
     */
    public static String sqlHash(String sql) {
        // 规范化SQL，移除多余空白
        String normalizedSql = sql.replaceAll("\\s+", " ").trim().toLowerCase();
        return md5(normalizedSql);
    }

    /**
     * 生成参数Map的哈希值
     * 
     * @param params 参数Map
     * @return 哈希值
     */
    public static String paramsHash(Map<String, Object> params) {
        // 使用TreeMap确保键的排序一致
        TreeMap<String, Object> sortedParams = new TreeMap<>(params);
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, Object> entry : sortedParams.entrySet()) {
            sb.append(entry.getKey()).append("=");
            if (entry.getValue() != null) {
                sb.append(entry.getValue().toString());
            } else {
                sb.append("null");
            }
            sb.append(";");
        }
        return md5(sb.toString());
    }

    /**
     * 将字节数组转换为十六进制字符串
     * 
     * @param bytes 字节数组
     * @return 十六进制字符串
     */
    private static String bytesToHex(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }
} 